package com.jcwy.common.registrar;

import com.jcwy.common.config.MysqlSyncPluginConfig;
import com.jcwy.common.listener.MysqlSourceExample;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.BeanFactory;
import org.springframework.beans.factory.BeanFactoryAware;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.ResourceLoaderAware;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ResourceLoader;
import org.springframework.core.type.AnnotationMetadata;
import org.springframework.util.ObjectUtils;

import java.util.function.Supplier;

/**
 * @author yicol
 * @version 1.0
 */
public class MysqlSyncPluginRegistrar
        implements ImportBeanDefinitionRegistrar, ResourceLoaderAware, EnvironmentAware, BeanFactoryAware {

    private ConfigurableListableBeanFactory beanFactory;

    @Override
    public void setEnvironment(Environment environment) {

    }

    @Override
    public void setResourceLoader(ResourceLoader resourceLoader) {

    }

    @Override
    public void registerBeanDefinitions(AnnotationMetadata metadata,
                                        BeanDefinitionRegistry registry) {

        /**
         * 自定义bean的注入，简单用法，也可以使用下面方式二
         */
        BeanDefinitionBuilder configBuilder = BeanDefinitionBuilder.rootBeanDefinition(MysqlSyncPluginConfig.class);
        registry.registerBeanDefinition(
                MysqlSyncPluginConfig.class.getSimpleName(),
                configBuilder.getBeanDefinition());

        BeanDefinitionBuilder customSinkBuilder = BeanDefinitionBuilder.genericBeanDefinition(MysqlSourceExample.class);
        registry.registerBeanDefinition(
                MysqlSourceExample.class.getSimpleName(),
                customSinkBuilder.getBeanDefinition());

        /**
         * 方式二
         * 自定义bean的注入，需要实现ImportBeanDefinitionRegistrar, ResourceLoaderAware, EnvironmentAware, BeanFactoryAware接口
         */
//        registerSyntheticBeanIfMissing(registry,MysqlSyncPluginConfig.class.getSimpleName(),MysqlSyncPluginConfig.class,MysqlSyncPluginConfig::new);
    }

    private <T> void registerSyntheticBeanIfMissing(BeanDefinitionRegistry registry, String name,
                                                    Class<T> beanClass, Supplier<T> instanceSupplier) {
        if (ObjectUtils.isEmpty(this.beanFactory.getBeanNamesForType(beanClass, true, false))) {
//            RootBeanDefinition beanDefinition = new RootBeanDefinition(beanClass, instanceSupplier);
            BeanDefinitionBuilder beanDefinition = BeanDefinitionBuilder.rootBeanDefinition(beanClass);
            beanDefinition.getBeanDefinition().setInstanceSupplier(instanceSupplier);
            beanDefinition.setSynthetic(true);
            registry.registerBeanDefinition(name, beanDefinition.getBeanDefinition());
        }
    }


    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        if (beanFactory instanceof ConfigurableListableBeanFactory) {
            this.beanFactory = (ConfigurableListableBeanFactory) beanFactory;
        }
    }
}
